# coding=utf-8
# Copyright (C) xxx team - All Rights Reserved
# 
# @Version:   3.10.4
# @Software:  PyCharm
# @FileName:  dummy_data.py
# @CTime:     2022/7/31 22:35   
# @Author:    yhy
# @Email:     yhy@yhy.com
# @UTime:     2022/7/31 22:35
# 
# @Description:
# 
#     xxx
# 
import codecs
import logging
from typing import List, Dict, Optional
import numpy as np
import random

logger = logging.getLogger(__name__)


def token_task(n_samples=128, seq_len_min=1, seq_len_max=100):
    """
    a toy task of **sorting** task. The output is the sorted indices of the input.
    // An example
    // Input :  [0, 3, 1, 2]
    // Output:  [0, 2, 3, 1]
    :param n_samples:
    :param seq_len:
    :return:
    """
    # Boundary tasks
    data, labels = [], []
    for _ in range(n_samples):
        inputs = np.random.permutation(range(1, random.randint(seq_len_min, seq_len_max) + 1)).tolist()
        target = sorted(range(len(inputs)), key=lambda k: inputs[k])
        data.append(inputs)
        labels.append(target)
    return data, labels


def seq_task(N):
    # generate Boundary tasks
    """
    Generates a set of N sequences of fixed length
    >Let’s try out some code on a toy problem. Pointer networks are really most relevant for recurrency-sensitive data sequences, so we’ll create one. Suppose we assume our input data is a sequence of integers between 0 and 10 (with possible duplicates) of unknown length. Each sequence always begins with low integers (random values between 1 to 5), has a run of high integers (random values between 6 to 10), then turns low again to finish (1 to 5).
    >For example, a sequence might be “4,1,2,3,1,1,6,9,10,8,6,3,1,1”, with the run of high integers in bold, surrounded by runs of low integers. We want to train a network that can point to these two change points — the beginning and end of the run of highs in the middle, regardless of the sequence length.

    // An example
    // Input : [4,1,2,3,1,1,6,9,10,8,6,3,1,1]
    // Output: [6, 10]
    """

    def generate_single_seq(length=30, min_len=5, max_len=10):
        """ Generates a sequence of numbers of random length and inserts a sub-sequence oh greater numbers at random place
        In the sequence model, the length of output is the same as the length of input. I put  See the following example.

        Input:
        length: total sequence length
        min_len: minimum length of sequence
        max_len: maximum length of sequence
        Output:
        sequence of numbers, index of the start of greater numbers subsequence"""
        seq_before = [(random.randint(1, 5)) for x in range(random.randint(min_len, max_len))]
        seq_during = [(random.randint(6, 10)) for x in range(random.randint(min_len, max_len))]
        seq_after = [random.randint(1, 5) for x in range(random.randint(min_len, max_len))]
        seqs = seq_before + seq_during + seq_after
        seqs = seqs + ([0] * (length - len(seqs)))
        return seqs, len(seq_before), len(seq_before) + len(seq_during) - 1

    data = []
    starts = []
    ends = []
    for i in range(N):
        seq, ind_start, ind_end = generate_single_seq()
        data.append(seq)
        starts.append(ind_start)
        ends.append(ind_end)
    return data, starts, ends


def main():
    token_datas = token_task(10)
    print(token_datas)


if __name__ == '__main__':
    main()




def onehot_encoder():
    C = 10
    B = 4
    label = torch.LongTensor(B, 1).random_(C)

    return torch.zeros(B, C, dtype=torch.int32).scatter_(1, label, 1)